import 'dart:async';
import 'dart:math';
import 'dart:ui';

import 'package:amap_map_fluttify/amap_map_fluttify.dart';
import 'package:detect/utils/db_util.dart';
import 'package:detect/utils/storage_util.dart';
import 'package:flutter/material.dart';
import 'package:flutter_localization/flutter_localization.dart';
import 'package:intl/intl.dart';

class Global {
  Global._();

  static final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();

  ///初始化
  static Future<void> init() async {
    await StorageUtil.init();
    await AmapService.instance.updatePrivacyAgree(true);
    await AmapService.instance.updatePrivacyShow(true);
    await AmapLocation.instance.updatePrivacyAgree(true);
    await AmapLocation.instance.updatePrivacyShow(true);
    await AmapLocation.instance.init(iosKey: '');
    await FlutterLocalization.instance.init(mapLocales: [
      const MapLocale('zh', {'title': '本地化'}),
      const MapLocale('en', {'title': 'Localization'})
    ], initLanguageCode: 'zh');
    await DBUtil.initDB("DB", [
      DBCreateTable("Radio", [
        "`id` INTEGER PRIMARY KEY",
        "`name` TEXT NOT NULL UNIQUE",
        "`type` INTEGER NOT NULL",
        "`antenna` INTEGER NOT NULL",
        "`lng` TEXT NOT NULL",
        "`lat` TEXT NOT NULL",
      ]),
      DBCreateTable("DisabledMHz", [
        "`id` INTEGER PRIMARY KEY AUTOINCREMENT",
        "`values` TEXT NOT NULL UNIQUE",
      ]),
      DBCreateTable("DetectTask", [
        "`id` INTEGER PRIMARY KEY AUTOINCREMENT",
        "`radio_id` INTEGER NOT NULL",
        "`type` TEXT NOT NULL",
        "`role` TEXT NOT NULL",
        "`name` TEXT NOT NULL UNIQUE",
        "`time` TEXT NOT NULL",
        "`disabled_mhz_id` INTEGER NOT NULL",
        "`state` INTEGER NOT NULL DEFAULT 0",
        "FOREIGN KEY(`radio_id`) REFERENCES DB_Radio(`id`) ON DELETE RESTRICT",
        "FOREIGN KEY(`disabled_mhz_id`) REFERENCES DB_DisabledMHz(`id`) ON DELETE RESTRICT",
      ]),
      DBCreateTable("DetectTaskBest", [
        "`id` INTEGER PRIMARY KEY AUTOINCREMENT",
        "`type` TEXT NOT NULL",
        "`name` TEXT NOT NULL UNIQUE",
        "`radio_id` INTEGER NOT NULL",
        "`start_time` TEXT",
        "`end_time` TEXT",
        "`time` TEXT NOT NULL",
        "`result_ids` TEXT NOT NULL",
        "FOREIGN KEY(`radio_id`) REFERENCES DB_Radio(`id`) ON DELETE RESTRICT",
      ]),
      DBCreateTable("GeneralTaskHours", [
        "`id` INTEGER PRIMARY KEY AUTOINCREMENT",
        "`detect_task_id` INTEGER NOT NULL",
        "`hour` INTEGER NOT NULL CHECK(`hour` >= 0 AND `hour` <= 23)",
        "`start_hz` INTEGER NOT NULL",
        "`end_hz` INTEGER NOT NULL",
        "`power` INTEGER NOT NULL",
        "FOREIGN KEY(`detect_task_id`) REFERENCES DB_DetectTask(`id`) ON DELETE CASCADE",
      ]),
      DBCreateTable("GeneralTaskResult", [
        "`id` INTEGER PRIMARY KEY AUTOINCREMENT",
        "`detect_task_id` INTEGER NOT NULL",
        "`time` TEXT NOT NULL",
        "`channel` INTEGER NOT NULL",
        "`hz` INTEGER NOT NULL",
        "`signal` REAL NOT NULL",
        "`noise` REAL NOT NULL",
        "`doppler` REAL NOT NULL",
        "`multi_path` REAL NOT NULL",
        "FOREIGN KEY(`detect_task_id`) REFERENCES DB_DetectTask(`id`) ON DELETE CASCADE",
      ]),
      DBCreateTable("PickTaskHours", [
        "`id` INTEGER PRIMARY KEY AUTOINCREMENT",
        "`detect_task_id` INTEGER NOT NULL",
        "`hour` INTEGER NOT NULL CHECK(`hour` >= 0 AND `hour` <= 23)",
        "`power` INTEGER NOT NULL",
        "`modem_type` TEXT NOT NULL",
        "`strategy` TEXT NOT NULL",
        "`hzs` TEXT NOT NULL",
        "FOREIGN KEY(`detect_task_id`) REFERENCES DB_DetectTask(`id`) ON DELETE CASCADE",
      ]),
      DBCreateTable("PickTaskResult", [
        "`id` INTEGER PRIMARY KEY AUTOINCREMENT",
        "`detect_task_id` INTEGER NOT NULL",
        "`time` TEXT NOT NULL",
        "`hz` INTEGER NOT NULL",
        "`sync_c0` REAL NOT NULL",
        "`lost_c0` REAL NOT NULL",
        "`sync_c1` REAL NOT NULL",
        "`lost_c1` REAL NOT NULL",
        "`sync_c3` REAL NOT NULL",
        "`lost_c3` REAL NOT NULL",
        "`snr_lora` REAL NOT NULL",
        "`snr_c0` REAL NOT NULL",
        "`snr_c1` REAL NOT NULL",
        "`snr_c3` REAL NOT NULL",
        "FOREIGN KEY(`detect_task_id`) REFERENCES DB_DetectTask(`id`) ON DELETE CASCADE",
      ]),
      DBCreateTable("PickTaskResultPackage", [
        "`id` INTEGER PRIMARY KEY AUTOINCREMENT",
        "`detect_task_id` INTEGER NOT NULL",
        "`result_id` INTEGER",
        "`time` TEXT NOT NULL",
        "`data` TEXT NOT NULL",
        "`channel` INTEGER NOT NULL",
        "`modem_type` TEXT NOT NULL",
        "`hz` INTEGER NOT NULL",
        "FOREIGN KEY(`detect_task_id`) REFERENCES DB_DetectTask(`id`) ON DELETE CASCADE",
        "FOREIGN KEY(`result_id`) REFERENCES DB_PickTaskResult(`id`) ON DELETE CASCADE",
      ],true),
      DBCreateTable("Chat", [
        "`id` INTEGER PRIMARY KEY AUTOINCREMENT",
        "`sender_id` INTEGER NOT NULL",
        "`receiver_id` INTEGER NOT NULL",
        "`content` TEXT NOT NULL",
        "`content_type` INTEGER NOT NULL",
        "`time` TEXT NOT NULL",
        "FOREIGN KEY(`sender_id`) REFERENCES DB_Radio(`id`) ON DELETE RESTRICT",
        "FOREIGN KEY(`receiver_id`) REFERENCES DB_Radio(`id`) ON DELETE RESTRICT",
      ]),
    ]);
  }

  ///设备尺寸
  static Size get windowSize => Size(window.physicalSize.width / window.devicePixelRatio, window.physicalSize.height / window.devicePixelRatio);

  ///设备padding
  static EdgeInsets get windowPadding => EdgeInsets.only(
        left: window.viewPadding.left / window.devicePixelRatio,
        top: window.viewPadding.top / window.devicePixelRatio,
        right: window.viewPadding.right / window.devicePixelRatio,
        bottom: window.viewPadding.bottom / window.devicePixelRatio,
      );

  ///设备insets
  static EdgeInsets get windowInsets => EdgeInsets.only(
        left: window.viewInsets.left / window.devicePixelRatio,
        top: window.viewInsets.top / window.devicePixelRatio,
        right: window.viewInsets.right / window.devicePixelRatio,
        bottom: window.viewInsets.bottom / window.devicePixelRatio,
      );

  ///动态尺寸
  static double ds(double pixel) => pixel / 1280 * (window.physicalSize.width / window.devicePixelRatio);

  static T? mins<T extends num>(List<T> nums) {
    if (nums.isNotEmpty) {
      num last = nums[0];
      for (T n in nums) {
        last = min(last, n);
      }
      return last as T;
    } else {
      return null;
    }
  }

  static T? maxs<T extends num>(List<T> nums) {
    if (nums.isNotEmpty) {
      num last = nums[0];
      for (T n in nums) {
        last = max(last, n);
      }
      return last as T;
    } else {
      return null;
    }
  }

  ///顶部导航栏封装
  static AppBar simpleAppBar(
    BuildContext context, {
    String? title,
    Color bgColor = Colors.white,
    Color fgColor = const Color.fromRGBO(48, 49, 51, 1),
    double bottomHeight = kToolbarHeight,
    Widget? bottom,
    List<Widget>? actions,
  }) {
    if (actions != null && actions.isNotEmpty) actions.add(VerticalDivider(width: ds(15), color: Colors.transparent));
    return AppBar(
      title: title == null ? null : Text(title),
      leadingWidth: ds(48),
      backgroundColor: bgColor,
      foregroundColor: fgColor,
      automaticallyImplyLeading: false,
      titleTextStyle: TextStyle(fontSize: Global.ds(18), fontWeight: FontWeight.w500, color: fgColor),
      leading: Navigator.canPop(context)
          ? GestureDetector(
              onTap: () => Navigator.maybePop(context),
              child: Container(padding: EdgeInsets.all(ds(15)), color: bgColor, child: Icon(Icons.arrow_back_ios, size: ds(18), color: fgColor)),
            )
          : null,
      actions: actions,
      bottom: bottom == null ? null : PreferredSize(preferredSize: Size.fromHeight(bottomHeight), child: SizedBox(height: bottomHeight, child: bottom)),
    );
  }

  ///日期时间格式化
  static String? parseTime(Object value, {String parse = 'yyyy-MM-dd HH:mm:ss', String resolve = 'yyyy-MM-dd HH:mm:ss'}) {
    DateFormat resolveFormat = DateFormat(resolve);
    if (value is String) {
      DateFormat parseFormat = DateFormat(parse);
      DateTime dateTime = DateTime.tryParse(value) ?? parseFormat.parse(value);
      return resolveFormat.format(dateTime);
    } else if (value is int) {
      return resolveFormat.format(DateTime.fromMillisecondsSinceEpoch(value));
    } else if (value is DateTime) {
      return resolveFormat.format(value);
    } else {
      return null;
    }
  }

  ///隐藏手机号中间6位
  static String hidePhone(String phone) => '${phone.substring(0, 3)}******${phone.substring(9)}';

  ///默认值
  static String defaultString(dynamic value, [String defaults = '-']) {
    defaults = defaults.isEmpty ? '-' : defaults;
    String? result = value?.toString();
    return result?.isEmpty ?? true ? defaults : result!;
  }

  ///保留小数位
  static double toFixed(num value, int fractionDigits) {
    String result = value.toString();
    if (result.contains(".") && result.split(".")[1].length > fractionDigits) {
      return double.parse(value.toStringAsFixed(fractionDigits));
    } else {
      return value.toDouble();
    }
  }
}
